package com.rongke.web;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.rongke.commons.JsonCodeEnum;
import com.rongke.commons.JsonResp;
import com.rongke.model.Admin;
import com.rongke.model.AdminPermission;
import com.rongke.model.AdminUserRole;
import com.rongke.redis.CacheUtil;
import com.rongke.service.AdminPermissionService;
import com.rongke.service.AdminService;
import com.rongke.service.AdminUserRoleService;
import com.rongke.utils.Md5;
import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import org.apache.log4j.Logger;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.util.*;

/**
 * @AdminController
 * @后台登录Controller
 * @version : Ver 1.0
 */
@RestController
@RequestMapping(value="/api/admin")
@Transactional
@CrossOrigin
public class AdminController {
    private Logger log = Logger.getLogger(this.getClass());
    @Autowired
    private AdminService adminService;
    @Autowired
    private CacheUtil cacheUtil;
    @Autowired
    private AdminPermissionService adminPermissionService;
    @Autowired
    private AdminUserRoleService adminUserRoleService;


    /**
     * @添加后台登录
     * @param admin
     * @return 返回值JsonResp
     */
    @RequestMapping(value="/add", method = RequestMethod.POST)
    public JsonResp addAdmin(@RequestBody Admin admin,String roleId){
        log.debug("添加后台登录");
        EntityWrapper<Admin> ew=new EntityWrapper<>();
        ew.eq("login_name",admin.getLoginName());
        Admin admin1=adminService.selectOne(ew);
        if(admin1!=null){
            return JsonResp.fa("该账号已注册");
        }
        admin.setPassword(Md5.md5Encode(admin.getPassword()));
        admin.setGmtDatetime(new Date());
        adminService.insert(admin);
        AdminUserRole adminUserRole=new AdminUserRole();
        adminUserRole.setAdminId(admin.getId());
        adminUserRole.setAdminRoleId(Integer.valueOf(roleId));
        adminUserRoleService.insert(adminUserRole);
        return JsonResp.ok();
    }

    /**
     * @修改管理
     * @param admin
     * @return 返回值JsonResp
     */
    @RequestMapping(value="/updateAdmin", method = RequestMethod.POST)
    public JsonResp updateAdmin(@RequestBody Admin admin,String roleId){
        log.debug("修改管理");
        Admin oldAdmin=adminService.selectById(admin.getId());
        oldAdmin.setLoginName(admin.getLoginName());
        oldAdmin.setPassword(Md5.md5Encode(admin.getPassword()));
        oldAdmin.setName(admin.getName());
        oldAdmin.setUptDatetime(new Date());
        adminService.updateById(oldAdmin);
        EntityWrapper<AdminUserRole> ew=new EntityWrapper<>();
        ew.eq("admin_id",oldAdmin.getId());
        List<AdminUserRole> oldAdminUserRoles=adminUserRoleService.selectList(ew);
        for (AdminUserRole ar:oldAdminUserRoles ) {
            ar.setAdminRoleId(Integer.valueOf(roleId));
        }
        adminUserRoleService.updateBatchById(oldAdminUserRoles);
        return JsonResp.ok();
    }


    /**
     * @修改后台登录
     * @param id
     * @return 返回值JsonResp
     */
    @RequestMapping(value="/deleteAdmin", method = RequestMethod.GET)
    public JsonResp deleteAdmin(Integer id){
        log.debug("修改后台登录");
       adminService.deleteById(id);
        return JsonResp.ok();
    }

    /**
     * @获取个人资料
     * @return 返回值JsonResp
     */
    @RequestMapping(value="/getadmin", method = RequestMethod.GET)
    public JsonResp getadmin(){
        log.debug("获取个人资料");
        Admin admin =adminService.currentUser();
        return JsonResp.ok(admin);
    }


    /**
     * @重置密码
     * @param adminId
     * @return 返回值JsonResp
     */
    @RequestMapping(value="/updatePassword", method = RequestMethod.GET)
    public JsonResp updatePassword(Integer adminId){
        log.debug("修改后台登录");
        Admin admin=adminService.selectById(adminId);
        admin.setPassword(Md5.md5Encode("123456"));
        adminService.updateById(admin);
        return JsonResp.ok();
    }
    /**
     * @根据id查找后台登录
     * @return 返回值JsonResp
     */
    @RequestMapping(value="/selectList", method = RequestMethod.GET)
    public JsonResp selectAdmin(){
        log.debug("查找后台登录");
        List<Map> admins = adminService.getAdminList();
        return JsonResp.ok(admins);
    }

    /**
     * @退出登录
     * @return 返回值JsonResp
     */
    @RequestMapping(value="/logout", method = RequestMethod.GET)
    public JsonResp logout(){
        log.debug("退出登录");
        adminService.logout();
        return JsonResp.ok();
    }

    /**
     * @获取后台当前登录者所有可见菜单列表
     * @return 返回值JsonResp
     */
    @RequestMapping(value="/getJurisdiction", method = RequestMethod.GET)
    public JsonResp getJurisdiction(){
        log.debug("获取后台当前登录者所有可见菜单列表");
        Admin admin=adminService.currentUser();
        if(admin==null){
            return JsonResp.fa(JsonCodeEnum.OVERTIME.getMessage());
        }
        Map condtion=new HashMap();
        condtion.put("loginName",admin.getLoginName());
        List<Map> admins = adminService.selectJurisdictionList(condtion);
        List<String> adminPermissionIds=new ArrayList<>();
        for (Map mp:admins) {
            adminPermissionIds.add(String.valueOf(mp.get("adminPermissionid")));
        }
        EntityWrapper<AdminPermission> ew=new EntityWrapper<>();
        ew.in("parentid",adminPermissionIds);
        List<AdminPermission> aps=adminPermissionService.selectList(ew);
        if(!cacheUtil.hasKey("menu"+admin.getLoginName())){
            int i=0,y=aps.size();
            String str[]=new String[y];
            for (;i<y;i++) {
                str[i]=aps.get(i).getUrl();
            }
            cacheUtil.addSet("menu"+admin.getLoginName(),str);
        }
        Map map=new HashMap();
        map.put("parentMenu",adminPermissionIds);
        map.put("menu",aps);
        return JsonResp.ok(map);
    }


    /**
     * @根据条件查找后台登录
     * @param admin
     * @return 返回值JsonResp
     */
    @RequestMapping(value = "/selectByCondition", method = RequestMethod.POST)
    public JsonResp selectAdminByCondition(@RequestBody Admin admin){
        log.debug("根据条件查找后台登录");
        if(admin==null)
            return JsonResp.toFail("参数不能为空");
        List<Admin> adminList=adminService.selectByCondition(admin);
        return JsonResp.ok(adminList);
    }



    /**
     * @后台登录
     * @return 返回值JsonResp
     */
    @RequestMapping(value="/login", method = RequestMethod.POST)
    public JsonResp login(@RequestBody Admin admin, HttpServletResponse response){
        log.debug("后台登录");
        String loginName=admin.getLoginName();
        UsernamePasswordToken token = new UsernamePasswordToken(loginName, Md5.md5Encode(admin.getPassword()));
        token.setRememberMe(true);
        System.out.print("为验证登录用户而封装的Token：");
        System.out.println(ReflectionToStringBuilder.toString(token, ToStringStyle.MULTI_LINE_STYLE));
        //获取当前的Subject
        Subject currentUser = SecurityUtils.getSubject();
        try {
            //在调用了login方法后，SecurityManager会收到AuthenticationToken，并将其发送给已配置的Realm执行必须的认证检查
            //每个Realm都能在必要时对提交的AuthenticationTokens作出反应
            //所以这一步在调用login(token)方法时，它会走到MyRealm.doGetAuthenticationInfo()方法中，具体验证方式详见此方法
            System.out.println("对用户[" + loginName + "]进行登录验证...验证开始");
            currentUser.login(token);
            System.out.println("对用户[" + loginName + "]进行登录验证...验证通过");
        }catch(UnknownAccountException uae){
            System.out.println("对用户[" + loginName + "]进行登录验证...验证未通过，未知账户");
            return JsonResp.fa("未知账户");
        }catch(IncorrectCredentialsException ice){
            System.out.println("对用户[" + loginName + "]进行登录验证...验证未通过，错误的凭证");
            return JsonResp.fa("密码不正确");
        }catch(LockedAccountException lae){
            System.out.println("对用户[" + loginName + "]进行登录验证...验证未通过，账户已锁定");
            return JsonResp.fa("账户已锁定");
        }catch(ExcessiveAttemptsException eae){
            System.out.println("对用户[" + loginName + "]进行登录验证...验证未通过，错误次数过多");
            return JsonResp.fa("用户名或密码错误次数过多");
        }catch(AuthenticationException ae){
            //通过处理Shiro的运行时AuthenticationException就可以控制用户登录失败或密码错误时的情景
            System.out.println("对用户[" + loginName + "]进行登录验证...验证未通过，堆栈轨迹如下");
            ae.printStackTrace();
            return JsonResp.fa("用户名或密码不正确");
        }

        //验证是否登录成功
        if(currentUser.isAuthenticated()){
            EntityWrapper<Admin> ew=new EntityWrapper<>();
            ew.eq("login_name",loginName);
            Admin admin1=adminService.selectOne(ew);
            admin1.setUptDatetime(new Date());
            admin1.setToken(currentUser.getSession().getId().toString());
            adminService.updateById(admin1);
            return JsonResp.ok(admin1);
        }else{
            token.clear();

        }
        return JsonResp.ok(admin);
    }






}
